      <h1 class="entry-title entry-title-single" itemprop="headline">SAP Bar Code 开发(03) &#8211; 后台作业任务实现条码编号归零</h1>

    <div class="entry-content entry-content-single entry-content-aside" itemprop="text">
      <p>在<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/barcode" title="查看Barcode中的全部文章" target="_blank">Barcode</a></span>开发中，条码标签内容都可以通过客户自定义编制；</p>
<p>通常情况下，流水号的编码都可以通过<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap" title="SAP" target="_blank">SAP</a></span>的编码范围（<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/number-range" title="查看Number Range中的全部文章" target="_blank">Number Range</a></span>）生成；</p>
<p>只是通常流水号都需要通过日期来生成，后面带出从数字1开始的流水，而对于<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap" title="SAP" target="_blank">SAP</a></span>的number range来说，只能不断累加，不能倒退；</p>
<p>因此，要实现每天归零操作，可以通过录制 BDC 实现归零操作，再将实现 BDC 的程序扔向后台任务，固定每天 00:00 执行任务。</p>
<p><span id="more-707"></span></p>
<p>&nbsp;</p>
<p><b>1.编码范围(<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/number-range" title="查看Number Range中的全部文章" target="_blank">Number Range</a></span>)</b></p>
<p>编码范围的定义，通过事务码 <strong>SNRO</strong>可以直接定义，这里不细说；</p>
<p>生成编码范围的程序如下：</p>
<pre class="brush: abap;">
*&#038;---------------------------------------------------------------------*
*&#038;      Form  frm_get_ref_nr
*&#038;---------------------------------------------------------------------*
*       获取 Number Range
*----------------------------------------------------------------------*
*      -->pv_object      text
*      -->pv_number      text
*      -->pv_out_nr      text
*----------------------------------------------------------------------*
FORM frm_get_ref_nr USING pv_object pv_number pv_out_nr.

DATA: lv_object       TYPE  tnro-object,
      Lv_nr_range_nr  TYPE  inri-nrrangenr.

  lv_object      = pv_object.   " 对象
  lv_nr_range_nr = pv_number.   "

  "锁定 Number Range 对象
  CALL FUNCTION 'NUMBER_RANGE_ENQUEUE'
    EXPORTING
      object           = lv_object
    EXCEPTIONS
      foreign_lock     = 1
      object_not_found = 2
      system_failure   = 3
      OTHERS           = 4.

  " 产生Number Range
  CALL FUNCTION 'NUMBER_GET_NEXT'
    EXPORTING
      nr_range_nr             = lv_nr_range_nr
      object                  = lv_object
    IMPORTING
      number                  = pv_out_nr
    EXCEPTIONS
      interval_not_found      = 1
      number_range_not_intern = 2
      object_not_found        = 3
      quantity_is_0           = 4
      quantity_is_not_1       = 5
      interval_overflow       = 6
      buffer_overflow         = 7
      OTHERS                  = 8.

  " 解锁 Number Range 对象
  CALL FUNCTION 'NUMBER_RANGE_DEQUEUE'
    EXPORTING
      object = lv_object.

  IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    "FRM_GET_NR

</pre>
<p>&nbsp;</p>
<p><b>2.录制BDC</b></p>
<p>事务码 SHDB 录制将相应编码范围状态值清零：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2015/03/barcode_03_maintain_number_range_intervals.jpg" alt="barcode_03_maintain_number_range_intervals" width="623" height="244" class="alignnone size-full wp-image-708" /></p>
<p>&nbsp;</p>
<p>录制后的BDC程序ZBC_NUMBER_RANGE_ZEROING：</p>
<pre class="brush: abap;">

REPORT  zbc_number_range_zeroing.
************************************************************************
*                  I N C L U D E                                       *
************************************************************************
INCLUDE zbdcrecx1.

************************************************************************
*                  S E L E C T I O N  S C R E E N                      *
************************************************************************
SELECTION-SCREEN BEGIN OF BLOCK block1.

PARAMETERS: cb_auto TYPE c AS CHECKBOX.

SELECTION-SCREEN END OF BLOCK block1.
************************************************************************
*                  I N I T I A L I Z A T I O N                         *
************************************************************************
INITIALIZATION.

************************************************************************
*                  T O P  O F  P A G E                                 *
************************************************************************

************************************************************************
*                  S T A R T  O F  S E L E C T I O N                   *
************************************************************************
START-OF-SELECTION.

* 条码归零
  PERFORM frm_data_process using 'ZBC_CODE'.

*&#038;---------------------------------------------------------------------*
*&#038;      Form  frm_data_process
*&#038;---------------------------------------------------------------------*
*       Data Process
*----------------------------------------------------------------------*
FORM frm_data_process USING pv_object.

  PERFORM bdc_dynpro      USING 'SAPMSNRO' '0150'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'NRIV-OBJECT'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=IUPD'.
  PERFORM bdc_field       USING 'NRIV-OBJECT'
                                pv_object.    "'ZBC_CODE'. "对象名称
  PERFORM bdc_dynpro      USING 'SAPMSNUM' '0100'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=LUPD'.
  PERFORM bdc_dynpro      USING 'SAPLSNR0' '0503'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'INRDP-NRLEVEL(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=SAVE'.
  PERFORM bdc_field       USING 'INRDP-NRLEVEL(01)'
                                '0'.
  PERFORM bdc_dynpro      USING 'SAPMSSY0' '0120'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=DBAC'.
  PERFORM bdc_dynpro      USING 'SAPLSNR0' '0503'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'INRDP-FROMNUMBER(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=ENDA'.
  PERFORM bdc_dynpro      USING 'SAPMSNRO' '0150'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'NRIV-OBJECT'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=ENDA'.
  PERFORM bdc_field       USING 'NRIV-OBJECT'
                                pv_object. "'ZBC_CODE'. "对象名称
  PERFORM bdc_transaction USING 'SNRO' 'N'.
*  ENDIF.

ENDFORM.                    "frm_data_process

</pre>
<p>其中，Include文件自定义了 BDC 用到的相关 Subroutine：</p>
<pre class="brush: abap;">

*&#038;---------------------------------------------------------------------*
*&#038;  Include                ZBDCRECX1
*&#038;---------------------------------------------------------------------*

*----------------------------------------------------------------------*
*   data definition
*----------------------------------------------------------------------*
*       Batchinputdata of single transaction
DATA:   bdcdata LIKE bdcdata    OCCURS 0 WITH HEADER LINE.
*       messages of call transaction
DATA:   messtab LIKE bdcmsgcoll OCCURS 0 WITH HEADER LINE.
*       error session opened (' ' or 'X')
DATA:   e_group_opened.
*       message texts
TABLES: t100.

*----------------------------------------------------------------------*
*        Start new transaction according to parameters                 *
*----------------------------------------------------------------------*
FORM bdc_transaction USING tcode ctumode.
  DATA: l_mstring(480).
  DATA: l_subrc LIKE sy-subrc.

  REFRESH messtab.
  CALL TRANSACTION tcode USING bdcdata
                   MODE   ctumode  " 跟踪显示 N不显示 E仅显示错误
                   UPDATE 'A'      " A异步    B同步   L本地更新
                   MESSAGES INTO messtab.
  l_subrc = sy-subrc.
  WRITE: / 'CALL_TRANSACTION',
           tcode,
           'returncode:'(i05),
           l_subrc,
           'RECORD:',
           sy-index.
  LOOP AT messtab.
    SELECT SINGLE * FROM t100 WHERE sprsl = messtab-msgspra
                              AND   arbgb = messtab-msgid
                              AND   msgnr = messtab-msgnr.
    IF sy-subrc = 0.
      l_mstring = t100-text.
      IF l_mstring CS '&#038;1'.
        REPLACE '&#038;1' WITH messtab-msgv1 INTO l_mstring.
        REPLACE '&#038;2' WITH messtab-msgv2 INTO l_mstring.
        REPLACE '&#038;3' WITH messtab-msgv3 INTO l_mstring.
        REPLACE '&#038;4' WITH messtab-msgv4 INTO l_mstring.
      ELSE.
        REPLACE '&#038;' WITH messtab-msgv1 INTO l_mstring.
        REPLACE '&#038;' WITH messtab-msgv2 INTO l_mstring.
        REPLACE '&#038;' WITH messtab-msgv3 INTO l_mstring.
        REPLACE '&#038;' WITH messtab-msgv4 INTO l_mstring.
      ENDIF.
      CONDENSE l_mstring.
      WRITE: / messtab-msgtyp, l_mstring(250).
    ELSE.
      WRITE: / messtab.
    ENDIF.
  ENDLOOP.
  REFRESH bdcdata.
ENDFORM.                    "BDC_TRANSACTION

*----------------------------------------------------------------------*
*        Start new screen                                              *
*----------------------------------------------------------------------*
FORM bdc_dynpro USING program dynpro.
  CLEAR bdcdata.
  bdcdata-program  = program.
  bdcdata-dynpro   = dynpro.
  bdcdata-dynbegin = 'X'.
  APPEND bdcdata.
ENDFORM.                    "BDC_DYNPRO

*----------------------------------------------------------------------*
*        Insert field                                                  *
*----------------------------------------------------------------------*
FORM bdc_field USING fnam fval.
  CLEAR bdcdata.
  bdcdata-fnam = fnam.
  bdcdata-fval = fval.
  APPEND bdcdata.
ENDFORM.                    "BDC_FIELD

</pre>
<p>&nbsp;</p>
<p><strong>3. 后台作业任务</strong></p>
<p>后台作业任务，通过事务码SM36定义，SM37管理。</p>
<p>&nbsp;</p>
<p>1) 任务启动条件</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2015/03/barcode_03_start_condition.jpg" alt="barcode_03_start_condition" width="658" height="100" class="alignnone size-full wp-image-712" /></p>
<p>包括以下几项：</p>
<p>立即执行(Immediate)</p>
<p>日期/时间(Date、Time) – 可以定义执行任务的日期、时间</p>
<p>作业之后(After <span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/job" title="查看Job中的全部文章" target="_blank">Job</a></span>) – 某个作业任务执行之后执行</p>
<p>事件之后(After event) – SAP事件处理之后执行</p>
<p>&nbsp;</p>
<p>这里需要每天都执行，因此，选择Date/Time，输入日期和时间；</p>
<p>然后在期间值（Period Values）内选择每天执行：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2015/03/barcode_03_period_values.jpg" alt="barcode_03_period_values" width="182" height="228" class="alignnone size-full wp-image-711" /></p>
<p>&nbsp;</p>
<p>2) 作业步骤</p>
<p>作业步骤可以通过三种方式执行：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2015/03/barcode_03_program_values.jpg" alt="barcode_03_program_values" width="662" height="95" class="alignnone size-full wp-image-710" /></p>
<p>通过<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap-abap" title="ABAP" target="_blank">ABAP</a></span>程序执行；</p>
<p>通过外部操作系统命令执行，通过SM69定义好命令后，输入命令名称；</p>
<p>通过外部程序执行；</p>
<p>&nbsp;</p>
<p>通常情况下，都是通过程序执行作业，在<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap-abap" title="ABAP" target="_blank">ABAP</a></span> Program中输入相应的程序名称：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2015/03/barcode_03_abap_program.jpg" alt="barcode_03_abap_program" width="644" height="112" class="alignnone size-full wp-image-709" /></p>
<p>&nbsp;</p>
<p>3) 作业选择</p>
<p>其中，在SM37中，包括以下几个管理状态：</p>
<p>已计划（Sched）: 后台作业的步骤（Step）已经定义，但是作业的开始条件（Start condition）没有定义。</p>
<p>已释放（Released）: 后台作业的步骤（Step）和开始条件（Start condition）都已经定义好了，并且相关的作业也经过有相关作业权限的人Release。</p>
<p>已取消（Canceled）: 作业非正常结束，包括两种情况：</p>
<p>1)、管理员通过SM37去主动Cancel相关作业；</p>
<p>2)、后台作业对应的程序有错误。</p>
<p>就绪（Ready）: 一个Released <span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/job" title="查看Job中的全部文章" target="_blank">Job</a></span>的开始条件（Start condition）已经满足，但是需要等待后台作业机制给这个作业分配工作进程。</p>
<p>激活的（Active）: 运行中的作业。运行中的作业不能被修改或者删除。</p>
<p>已完成（Finished）: 后台作业中预设的每个步骤（Step）都全部成功完成。</p>
<p>&nbsp;</p>
<p>保存成功后，点击执行，即可。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>